package main

import (
	"encoding/json"
	"fmt"
	"net"
	"os"
	"time"
)

// Config 配置文件结构体
type Config struct {
	IPAddress string `json:"ip_address"`
	Port      string `json:"port"`
	PeerIP    string `json:"peer_ip"`
}

// Message 消息结构体
type Message struct {
	Type    string `json:"type"`
	Content string `json:"content"`
}

var (
	config Config
	active bool
)

func main() {
	loadConfig("config.json")
	active = false
	go startHeartbeat()
	go startListener()
	select {}
}

// loadConfig 加载配置文件
func loadConfig(filename string) {
	data, err := os.ReadFile(filename)
	if err != nil {
		panic(err)
	}
	err = json.Unmarshal(data, &config)
	if err != nil {
		panic(err)
	}
}

// startHeartbeat 启动心跳检测
func startHeartbeat() {
	addr, err := net.ResolveUDPAddr("udp", config.PeerIP+":"+config.Port)
	if err != nil {
		panic(err)
	}
	conn, err := net.DialUDP("udp", nil, addr)
	if err != nil {
		panic(err)
	}
	defer conn.Close()
	for {
		message := Message{Type: "heartbeat", Content: ""}
		data, _ := json.Marshal(message)
		_, err := conn.Write(data)
		if err != nil {
			fmt.Println("Heartbeat failed:", err)
			handleFailure()
		}
		time.Sleep(2 * time.Second)
	}
}

// handleFailure 处理故障转移
func handleFailure() {
	if !active {
		active = true
		fmt.Println("Became active")
		syncConfig()
	}
}

// syncConfig 同步配置文件
func syncConfig() {
	addr, err := net.ResolveUDPAddr("udp", config.PeerIP+":"+config.Port)
	if err != nil {
		panic(err)
	}
	conn, err := net.DialUDP("udp", nil, addr)
	if err != nil {
		panic(err)
	}
	defer conn.Close()
	configData, _ := json.Marshal(config)
	message := Message{Type: "config", Content: string(configData)}
	data, _ := json.Marshal(message)
	conn.Write(data)
}

// startListener 启动监听器
func startListener() {
	addr, err := net.ResolveUDPAddr("udp", ":"+config.Port)
	if err != nil {
		panic(err)
	}
	conn, err := net.ListenUDP("udp", addr)
	if err != nil {
		panic(err)
	}
	defer conn.Close()
	buf := make([]byte, 1024)
	for {
		n, _, err := conn.ReadFromUDP(buf)
		if err != nil {
			continue
		}
		var message Message
		json.Unmarshal(buf[:n], &message)
		handleMessage(message)
	}
}

// handleMessage 处理消息
func handleMessage(message Message) {
	switch message.Type {
	case "heartbeat":
		fmt.Println("Received heartbeat")
	case "config":
		var receivedConfig Config
		json.Unmarshal([]byte(message.Content), &receivedConfig)
		if receivedConfig.IPAddress != config.IPAddress {
			config = receivedConfig
			saveConfig()
		}
	}
}

// saveConfig 保存配置文件
func saveConfig() {
	data, _ := json.Marshal(config)
	os.WriteFile("config.json", data, 0644)
}
